package com.golf.client.course.renderer;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferStrategy;
import java.util.concurrent.CopyOnWriteArrayList;


/**
 * A class that this able to render several registered layers
 * onto a single canvas.
 * 
 * @author gfloodgate
 */
public class CompositeRenderer 
{

	/** The constant number of buffers needed for double-buffering. */
	private static final int DOUBLE_BUFFER = 2;

	/** The collection of renderers that are compositied. */
	private final CopyOnWriteArrayList<CanvasRenderer> renderers = new CopyOnWriteArrayList<CanvasRenderer>();
	
	
	/** The canvas that this renderer works on. */
	private final Canvas canvas;
	
	/** The buffering strategy that is being used by this renderer. */
	private final BufferStrategy strategy;
	
	
	/**
	 * Create an instance of a composite renderer.
	 * 
	 * @param canvas The canvas that should be rendered onto.
	 */
	public CompositeRenderer(final Canvas canvas)
	{
		this.canvas = canvas;
		
		this.canvas.createBufferStrategy(DOUBLE_BUFFER);
		this.strategy = canvas.getBufferStrategy();
	}
	
	
	/**
	 * Add a layer renderer to the render chain.
	 * 
	 * @param renderer The renderer to add.
	 */
	public void addLayerRenderer(final CanvasRenderer renderer)
	{
		renderers.add(renderer);
	}
	
	
	/**
	 * Update the canvas with the sum rendition of all registered layers.
	 */
	public void update()
	{
		// Get the graphics renderer.
		final Graphics g = strategy.getDrawGraphics();
		
		// Add anti-aliasing, we like it.
		final Graphics2D g2d = (Graphics2D)g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		// CRUDE: Each renderer in the list is called.
		// full repait each time, etc. make better.
		for (final CanvasRenderer renderer : renderers)
		{
			renderer.render(g, canvas.getSize());
		}

		// Draw, and flip.
		g.dispose();
		strategy.show();
	}
	
}
